// ==UserScript==
// @name				[PHPhulp] UBBBar
// @namespace		http://phphulp.ikhoefgeen.nl/ubb
// @description	UBB-balk met sneltoetsen
// @include			http://*.phphulp.nl/*
// @include			http://phphulp.nl/*
// @include			http://phphulp.ikhoefgeen.nl/ubb/*
// ==/UserScript==

(function() {
/**
 * Als deze true is, dan zijn de klassen door de pagina aan te roepen.
 * Op deze manier kan je 'plugins' maken voor de ubb-bar. Zo zou het
 * mogelijk moeten zijn om knoppen via greasekit/greasemonkey-scripts van
 * derden, of door websites zelf extra functionaliteit aan te bieden.
 */

var EXPOSE_API = true;

var COLOUR = 'blue'; // blue or grey

var RESOURCES 	= 'http://phphulp.ikhoefgeen.nl/ubb/revisited/Resources';
RESOURCES = 'http://localhost/werk/phphulp.nl/ubbbar/Resources'; // voor thuis debug
var SCRIPTS 	= 'http://phphulp.ikhoefgeen.nl/ubb/revisited/Scripts';

var _IHGToolbarButtons = [];
var _IHGToolbars = [];
var _uniqueID = 0;
var _IHGUBBStylesheetLayout, _IHGUBBStylesheetColour;

/**
 * With-statements kijken naar het object bovenin opgegeven. Definieer je
 * een eigenschap die nog niet bestaat, dan valt hij terug op de scope, en
 * uiteindelijk op window. Alleen Internet Explorer kent style.filter. Bij
 * alle andere browsers gaat hij dus window.filter proberen te setten, en
 * daarij zou hij bestaande functies kunnen overschrijven. En dat willen we
 * natuurlijk niet. Vandaar deze variabele.
 */
var filter = null;

<? include 'ubbbar.user.String.js' ?>

<? include 'ubbbar.user.IHG.js' ?>

var blink = IHG.blink;
var each = IHG.each;
var $ = IHG.$;


/* W3C Compatible variant */
<? include 'ubbbar.user.IHG.SelectionController.js' ?>

IHG.SelectionController.model = 'w3c';
<? include 'ubbbar.user.IHG.SelectionController.W3C.js' ?>

/**
 * Internet Explorer support
 * "OMG - Ik heb een monster geschapen!"
 */
if(navigator.appName != 'Opera' && typeof document.selection == 'object') {
	<? include 'ubbbar.user.IHG.SelectionController.IE.js' ?>
}

<?php include 'ubbbar.user.IHG.Toolbar.js' ?>

<?php include 'ubbbar.user.IHG.Toolbar.Button.js' ?>

<?php include 'ubbbar.user.IHG.Toolbar.Spacer.js' ?>

<?php include 'ubbbar.user.IHG.Toolbar.Default.js' ?>

with(IHG.Toolbar) {
	Default.addButton(new Button({
		label: 'Vet',	
		image: RESOURCES + '/bold.png',
	shortcut: Keys.CMD + 'b',
		  tag: ['[b]', '[/b]']
	}));
		
	Default.addButton(new Button({
		label: 'Schuin',
		image: RESOURCES + '/italic.png',
	shortcut: Keys.CMD + 'i',
		  tag: ['[i]', '[/i]']
	}));
	
	Default.addButton(new Button({
			label: 'Onderstreep',  
			image: RESOURCES + '/underline.png',
		shortcut: Keys.CMD + 'u',
			  tag: ['[u]', '[/u]']
	}));
	
	Default.addButton(new Button({
			label: 'Doorhalen',
			image: RESOURCES + '/strikethrough.png',
		shortcut: Keys.CMD + 's',
		  	  tag: ['[s]', '[/s]']
	}));
	
	Default.addButton(new Spacer());
	
	Default.addButton(new Button({
			label: 'Afbeelding',	 
			image: RESOURCES + '/image.png',
		shortcut: null,
			  tag: ['[img]', '[/img]'],
	  condition: function(sender) {
					with(sender.selectionController) {	
						if(isMarked('[code]', '[/code]')
						|| isMarked('[', ']')) {
							this.state = DISABLED;
						} else if(selectionLength() > 0 && !IHG.URL_PATTERN.test(selection())) {
							this.state = DISABLED;
						} else if(isMarked('[img]', '[/img]')) {
							this.state = ACTIVE;
						} else {
							this.state = ENABLED;
						}
					}
				}
	}));
	
	Default.addButton(new Button({
			label: 'Link',
			image: RESOURCES + '/link.png',
		shortcut: Keys.CMD + 'l',
			  tag: [/\[url(?:=[\w#!:.?+=&%@!-\/]+?)?\]/, '[/url]'],
		   action: function(sender) {
			with(sender.selectionController) {
				if(this.state === IHG.Toolbar.DISABLED) return;

				if(isWrapped(this.tag[0], this.tag[1])) {
					unwrap(this.tag[0], this.tag[1]);
				} else if(isMarked(this.tag[0], this.tag[1])) {
					mark(this.tag[0], this.tag[1]);
				} else if(selection().match(IHG.URL_PATTERN)) {
					mark('[url=' + selection() + ']', '[/url]');
				} else {
					mark('[url]', '[/url]');
				}
			}
		}
	}));
	
	/*
	Default.addButton(new Button({
			label: 'Link',	 
			image: RESOURCES + '/link.png',
		shortcut: Keys.CMD + 'l',
		  action: function(sender) {
					with(sender.selectionController) {
						if(this.state === DISABLED)
							return;
						
						if(isMarked(/\[url=?[a-z0-9\.\:\\\/\@]*?\]/, '[/url]')) {
							console.log('marked');
							unwrap(/\[url=?[a-z0-9\.\:\\\/\@]*?\]/, '[/url]');
						} else {
							if(IHG.URL_PATTERN.test(selection())) {
								console.log('selection is url');
								mark('[url=' + selection() + ']', '[/url]');
							} else {
								console.log('mark with url');
								mark('[url]','[/url]');
							}
						}
					}
				},
	  condition: function(sender) {
					with(sender.selectionController) {
						if(isMarked('[code]', '[/code]') || isMarked('[img]', '[/img]')) {
							this.state = DISABLED;
						} else if(isMarked(/\[url=?[a-z0-9\.\:\\\/\@]*?\]/, '[/url]')) {
							this.state = ACTIVE;
						} else {
							this.state = ENABLED;
						}
					}
				}
	}));
	*/
	
	Default.addButton(new Spacer());
		
	Default.addButton(new Button({
			label: 'Quote',  
			image: RESOURCES + '/quote.png',
		shortcut: null,
		  action: function(sender) {
					with(sender.selectionController) {
						if(this.state == DISABLED)
							return;
						
						if(this.state == ENABLED) {
							wrap('[quote]', '[/quote]');
						} else {
							unwrap('[quote]', '[/quote]');
						}
					}
				},
	  condition: function(sender) {
					this.state = ENABLED;
					
					if(sender.carrotIsBetween('[code]', '[/code]')
					|| sender.carrotIsBetween('[', ']')) {
						this.state = DISABLED;
					} else if(sender.carrotIsBetween('[quote', '[/quote]')) {
						this.state = ACTIVE;
					}
				}
	}));
	
	Default.addButton(new Spacer());//.width = 210;
	
	Default.addButton(new Button({
			label: 'Report bug',
	  showLabel: true,
			image: RESOURCES + '/bug_add.png',
		shortcut: null,
		  action: function(sender) {
					window.open( 
						('http://bogus.ikhoefgeen.nl/codetrack.php?'
						+ 'page=login'
						+ '&userLogin[project_name]=IHG%20UBBBar'
						+ '&userLogin[username]=phphulp'
						+ '&userLogin[password]=phphulp'
						+ '&bypass=true'
						+ '&redirectTo=newIssue%26version=' + VERSION),
						
						'_blank',
						
						('width=800'
						+ ',height = 800'
						+ ',status=no'
						+ ',menubar=no'
						+ ',directories=no'
						+ ',toolbar=no'
						+ ',resizable=yes'
						+ ',scrollbars=no'));
				},
	   condition: function(sender) {
					this.state = ENABLED;
				}
	}));
	
	Default.addButton(new Button({
			label: 'Groter',
	  showLabel: true,
			image: RESOURCES + '/arrow_out.png',
		shortcut: null,
		  action: function(sender) {
				if(this.state === ACTIVE) {
					sender.txtarea.parentNode.className = sender.txtarea.parentNode.className.replace('IHGFullSized', '');
					if(sender.placeholderNode) {
						sender.container.parentNode.removeChild(sender.placeholderNode);
					}
				} else {
					sender.placeholderNode = document.createElement('div');
					with(sender.placeholderNode.style) {
						width = sender.container.offsetWidth;
						height = sender.container.offsetHeight;
					}
					sender.container.parentNode.insertBefore(sender.placeholderNode, sender.container);
					sender.container.className += ' IHGFullSized';
				}
			},
		condition: function(sender) {
			if(sender.txtarea.parentNode.className.match('IHGFullSized')) {
				this.state = ACTIVE;
				this.label = 'Kleiner';
			} else {
				this.state = ENABLED;
				this.label = 'Groter';
			}
		}
	}))
	
	Default.addButton(new Button({
			label: 'Instellingen',
	  showLabel: false,
			image: RESOURCES + '/bullet_wrench.png',
		shortcut: null,
		  action: function(sender) {
				var newColour = prompt('Kleur: (blue/grey)', COLOUR);
				if(newColour) {
					IHG.Preferences.set('ubbbar.colour', newColour);
				}
			},
		condition: function(sender) {
			this.state = ENABLED;
		}
	}))
}

try {
	COLOUR = IHG.Preferences.get('ubbbar.colour', COLOUR);
} catch(e) {}

/* alle textareas in de pagina voorzien van een balkje :) */
with(_IHGUBBStylesheetLayout = document.createElement('link')) {
	setAttribute('rel', 'stylesheet');
	setAttribute('type', 'text/css');
	setAttribute('href', RESOURCES + '/ubbbar.user.css');
}

with(_IHGUBBStylesheetColour = document.createElement('link')) {
	setAttribute('rel', 'stylesheet');
	setAttribute('type', 'text/css');
	setAttribute('href', RESOURCES + '/ubbbar.user.' + COLOUR + '.css');
}

with(document.getElementsByTagName('head')[0]) {
	appendChild(_IHGUBBStylesheetLayout)
	appendChild(_IHGUBBStylesheetColour);
}

/**
 * De oude methode, die alle txtarea's vervangt. Maar het is er maar eentje
 * op PHPhulp, en hij is ook nog eens hardnekkig, want hij zit niet binnen
 * het form-element volgens de DOM-tree.
 */
/*
var UBBtextareas = document.getElementsByTagName('textarea');
for(var i = 0; i < UBBtextareas.length; i++) {
	var bar	= new IHG.Toolbar.initWithDefaults(UBBtextareas[i]);
	_IHGToolbars.push(bar);
}
*/

var subjectArea = document.getElementsByTagName('textarea');
if(subjectArea.length > 0) {
	subjectArea = subjectArea[0];
	var form = subjectArea.form; // het form-element pakken
	
	/**
	 * de submitbutton heet submit, waardoor hij de functie submit() van het 
	 * form-element onderuit haalt. Hernoemen zou voldoende moeten zijn.
	 */
	for(var i = 0; i < form.elements.length; i++) {
		if(form.elements[i].name == 'submit') {
			form.elements[i].name = 'submitbutton';
			form.submitForm = form.submit;
			form.elements[i].name = 'submit';
			break;
		}
	}		
	
	/**
	 * De hierarchie in de DOM-tree herstellen, zodat de input-elementen
	 * en belangrijker, mijn textarea weer binnen het form-element vallen
	 */
	if(form.childNodes.length == 0) {
		var table = form.parentNode; // de bovenliggende node, met daarin de form-elementen
		table.parentNode.insertBefore(form, table); // form voor de table plaatsen
		form.appendChild(table); // table binnen het form-element hangen
	}
	// en nu dat de DOM-tree weer klopt:
	var bar = IHG.Toolbar.initWithDefaults(subjectArea);
	_IHGToolbars.push(bar);
}

window.IHGToolbarButtons = _IHGToolbarButtons;

/* voor plugins */
if(EXPOSE_API) {
	window.IHG = IHG;

	if(window.IHGOnload) {
		window.IHGOnload(IHG);
	}
		
	if(window.unsafeWindow) {
		alert(typeof window.unsafeWindow);
		window.unsafeWindow.IHG = window.IHG;
	}
}

})();
